package com.fingard.dsp.bank.directbank.citic01;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.IStatement;
import com.fingard.dsp.bank.reqrespobj.statement.ReqQryStatement;
import com.fingard.dsp.bank.reqrespobj.statement.RetAtsStatement;
import com.fingard.dsp.bank.reqrespobj.statement.TransState;
import com.fingard.dsp.bank.reqrespobj.statement.detail.RetAtsStatementDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;
import com.fingard.util.ZipUnZip4NetUtils;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import sun.misc.BASE64Decoder;

/**
 * 中信银行对账单获取
 * 
 * @author fanghh
 * @date 2019/4/15
 */
public class CITIC01Statement extends CITIC01Base implements IStatement {
	/**
	 * 支持如下业务：
	 * 		1、银联(单笔、批量)代付对私账单查询(198808)
	 * 		2、POS对账单
	 */
	@Override
	public RetAtsStatement d_Qry_Statement(ReqQryStatement p_reqQrySttm) throws Exception {
		RetAtsStatement retAts = new RetAtsStatement(p_reqQrySttm);
        retAts.writeStart();
        
        String[] tmpStandardHeader = getStandardStatement(p_reqQrySttm, retAts);
        String tmpStandardTotalNum = retAts.totalNum;
        if ("".equals(tmpStandardTotalNum)) {
        	tmpStandardTotalNum = "0";
		}
        
        String[] tmpPosRecRespHeader = getPosRecStatement(p_reqQrySttm, retAts);
        String tmpPosRecTotalNum = retAts.totalNum;
        if ("".equals(tmpPosRecTotalNum)) {
        	tmpPosRecTotalNum = "0";
		}
        
        if ("-1".equals(tmpPosRecRespHeader[0]) && "-1".equals(tmpStandardHeader[0])) {
			retAts.writeRespCode("-1");
			retAts.writeRespInfo("POS对账单获取失败,原因:" + tmpPosRecRespHeader[1] + ",单笔及批量付款对账单获取失败,原因:" + tmpStandardHeader[1]);
		} else {
			if (retAts.getWrittenRdCount() == 0) {
				retAts.writeRespCode("0");
				String respInfo = tmpPosRecRespHeader[1];
				if (StringHelper.isNullOrEmpty(respInfo)) {
					respInfo = tmpStandardHeader[1];
				}
				if (StringHelper.isNullOrEmpty(respInfo)) {
					respInfo = "交易为空";
				}
				retAts.writeRespInfo(respInfo);
			} else {
				retAts.isWritedTotalNum(String.valueOf(Integer.parseInt(tmpPosRecTotalNum) + Integer.parseInt(tmpStandardTotalNum)));
			}
		}

        retAts.writeEnd();
        return retAts;
	}
	
	/**
	 * 银联(单笔、批量)代付对私账单查询(198808)
	 * 
	 * @param p_reqQrySttm
	 * @return
	 * @throws Exception
	 */
	public String[] getStandardStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
		String[] respHeader = new String[]{"", ""};
		
		String tmpRespCode = "";
		String tmpRespInfo = "";
		
		retAts.totalNum = "0";
		int totalNum = 0;
		
		try {
			CITIC01Header bankHeader = new CITIC01Header();
			bankHeader.action = "DLUPRDWN"; // 对私付款-对账文件
			
			XmlTextWriter xmlWriter = new XmlTextWriter();
			writeCommonHeader(xmlWriter, bankHeader);
			xmlWriter.writeElementString("checkDate", p_reqQrySttm.busDate);
			xmlWriter.writeElementString("accountNo", p_reqQrySttm.actNum);
			xmlWriter.writeEndDocument();
			
			String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
			
			if(tmpStrRet[0].length() == 0) {
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
				if(tmpBkReader != null){
					String tmpStatus = tmpBkReader.getFirstText("/stream/status");
					String tmpStatusText = tmpBkReader.getFirstText("/stream/statusText");
					if(tmpStatus != null && tmpStatus.equals("AAAAAAA")){
						if(tmpBkReader.read("/stream/list")) {
							if(tmpBkReader.readedXElement.getAttrValue("name").equals("userDataList")) {
								tmpRespCode = "0";
								
								String tmpEncryptMsg = tmpBkReader.readedXElement.getSingleText("row/fileContent");
								WriteBankLogLn2("对私付款账单文件密文:\r\n" + tmpEncryptMsg);
								
								byte[] tmpEncryptBytes = new BASE64Decoder().decodeBuffer(tmpEncryptMsg);
								String tmpPlianMsg = new String(ZipUnZip4NetUtils.uncompress(tmpEncryptBytes), getCharset());
								WriteBankLogLn2("对私付款账单文件明文:\r\n" + tmpPlianMsg);
								
								StringReader strReader = new StringReader(tmpPlianMsg);
								BufferedReader tmpReader = new BufferedReader(strReader);
								tmpReader.readLine();
								tmpReader.readLine();
								tmpReader.readLine();
								
								while (true) {
									String eachline = tmpReader.readLine();
									if (eachline == null) {
										break;
									}
									
									String[] eachNodeArr = eachline.split(",");
									if (eachNodeArr.length == 14) {
										RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();
										
										String tranState = eachNodeArr[10];
										if ("3".equals(tranState) || "1".equals(tranState)) {
											totalNum++;
											
											if (StringHelper.isNullOrEmpty(eachNodeArr[3])) {
												tmpRetDetail.askNumber = eachNodeArr[0];
											} else {
												tmpRetDetail.askNumber = eachNodeArr[13];
												tmpRetDetail.reqBatchNO = eachNodeArr[0];
											}
											
											tmpRetDetail.amount = eachNodeArr[6];
											tmpRetDetail.busTime = Format.DateTime14Format.format(eachNodeArr[2]);
											tmpRetDetail.oppAct = eachNodeArr[4];
											tmpRetDetail.oppActName = eachNodeArr[5];
											tmpRetDetail.transState = TransState.Success;
											tmpRetDetail.transMsg = eachNodeArr[11];
											
											retAts.writeRetDetail(tmpRetDetail);
										} 
									} else {
										break;
									}
								}
							} else {
								tmpRespCode = "-1";
								tmpRespInfo = "未找到userDataList的list";
							}
						} else {
							tmpRespCode = "-1";
							tmpRespInfo = "未找到/stream/list";
						}
					} else {
						tmpRespCode = "-1";
						tmpRespInfo = tmpStatusText;
					}
				} else {
					tmpRespCode = "-1";
					tmpRespInfo = tmpSbMsg.toString();
				}
			} else {
				tmpRespCode = "-1";
				tmpRespInfo = tmpStrRet[1];
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRespCode = "-1";
			tmpRespInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		retAts.totalNum = String.valueOf(totalNum);

        respHeader[0] = tmpRespCode;
        respHeader[1] = tmpRespInfo;

        return respHeader;
	}

	/**
     * POS对账单
     * 
     * @param p_reqQrySttm
     * @param retAts
     * @return
     * @throws Exception
     */
    private String[] getPosRecStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
        String[] respHeader = new String[]{"", ""};
        
        String tmpRespCode = "";
        String tmpRespInfo = "";
        
        retAts.totalNum = "0";
        int totalNum = 0;
        
        try {
        	if (StringHelper.isNullOrEmpty(p_reqQrySttm.channel)) {
        		ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "pos01");
    			if (actItem == null) {
    				respHeader[0] = "-1";
    				respHeader[1] = "未找到账号:[" + p_reqQrySttm.actNum + "]商户配置信息";
    				return respHeader;
    			}
        	}
        	
            FtpSet ftpSet = bankFront.getFtpSet("pos");
            ftpSet.downDir = StringHelper.trimEnd(ftpSet.getDownDir("pos"), "/") + "/" + p_reqQrySttm.busDate;
            WriteBankLogLn2("中信银行POS对账单SFTP服务器地址:" + ftpSet.serverIP + ":" + ftpSet.port);

            StringBuilder sbFileContent = new StringBuilder();
            
            String tmpPosMode = getBankConfig().getValueAsString("posRecUseVersion");
            if ("B".equals(tmpPosMode)) {
            	String downFileName = p_reqQrySttm.actNum + p_reqQrySttm.busDate + ".txt";
                WriteBankLogLn2("中信银行POS对账单所在服务器路径:" + ftpSet.downDir + "/" + downFileName);

                String localFilePath = createTempFileDirectory() + File.separator + downFileName;
                WriteBankLogLn2("中信银行POS对账单保存本地路径:" + localFilePath);

                FtpReceiver ftpReceiver = null;
    			String posRecRequestType = getBankConfig().getValueAsString("posRecRequestType");
    			if ("ftp".equals(posRecRequestType.toLowerCase())) {
    				FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
    	            ftpReceiver = ftpPortClient.downloadFile(downFileName, localFilePath);
    			} else if ("sftp".equals(posRecRequestType.toLowerCase())) {
    				SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
    				String sftpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + downFileName;
    				WriteBankLogLn2("待下载SFTP服务器文件路径:\r\n" + sftpFilePath);
    				ftpReceiver = sftpPortClient.downloadFile("",sftpFilePath, localFilePath);
    			}
                if (ftpReceiver.isCompleted) {
                    if (sbFileContent.length() > 0) {
                        sbFileContent.append("\n");
                    }
                    sbFileContent.append(FileHelper.readFileText(localFilePath, getCharset("UTF-8", "pos")));
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = "中信银行POS对账单下载失败,原因:\r\n" + ftpReceiver.connMsg;
                }
            } else {
            	tmpRespCode = "-1";
                tmpRespInfo = "对账单版本错误,当前版本为:[" + tmpPosMode + "].";
            }
            if (StringHelper.hasAnyChar(sbFileContent.toString())) {
            	tmpRespCode = "0";
            	
                String tmpStrRet = sbFileContent.toString();
                WriteBankLogLn2("中信银行POS对账单响应数据:\r\n" + tmpStrRet);

                StringReader strReader = new StringReader(tmpStrRet);
                BufferedReader tmpReader = new BufferedReader(strReader);

                boolean isContinue = false;
                while (true) {
                    String eachline = tmpReader.readLine();
                    if (eachline == null) {
                        break;
                    }
                    if ("".equals(eachline.trim())) {
                        continue;
                    }
                    String[] detailNodes = eachline.split("`~");
                    if (p_reqQrySttm.actNum.equals(detailNodes[1].trim())) {
                        totalNum++;
                        isContinue = true;
                        RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();

                        if (StringHelper.hasAnyChar(detailNodes[4])) {
                            tmpRetDetail.askNumber = detailNodes[4].trim();
                        }

                        tmpRetDetail.cdFlag = "22";

                        if (StringHelper.hasAnyChar(detailNodes[11])) {
                            tmpRetDetail.amount = StringHelper.amountDivide100(detailNodes[11].trim());
                        }

                        if (detailNodes.length > 15) {
                        	if (StringHelper.hasAnyChar(detailNodes[15])) {
                                tmpRetDetail.fee = StringHelper.amountDivide100(detailNodes[15].trim());
                            }
                        }

                        tmpRetDetail.busTime = detailNodes[6];

                        if (StringHelper.hasAnyChar(detailNodes[7])) {
                            tmpRetDetail.oppAct = detailNodes[7].trim();
                        }

                        if (StringHelper.hasAnyChar(detailNodes[8])) {
                            tmpRetDetail.oppActName = detailNodes[8].trim();
                        }

                        if ("2".equals(detailNodes[13].trim())) {
                            tmpRetDetail.transState = TransState.Success;
                        } else {
                            tmpRetDetail.transState = TransState.Fail;
                        }

                        retAts.writeRetDetail(tmpRetDetail);
                    }
                }

                if (!isContinue) {
                    tmpRespCode = "0";
                    tmpRespInfo = "没有符合条件的记录!";
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.totalNum = String.valueOf(totalNum);

        respHeader[0] = tmpRespCode;
        respHeader[1] = tmpRespInfo;

        return respHeader;
    }
}
